package model

import "github.com/jinzhu/gorm"

type (
	ActionResources []*ActionResource

	ActionResource struct {
		Model
		ActionID uint   `json:"action_id" yaml:"-" gorm:"column:action_id;index;not null;"`
		Method   string `json:"method" yaml:"method" gorm:"column:method;size:255;default:'';not null;"`
		Path     string `json:"path" yaml:"path" gorm:"column:path;size:255;default:'';not null;"`
	}
)

func CreateActionResource(ar *ActionResource, tx *gorm.DB) error {
	return tx.Create(ar).Error
}

func DeleteActionResource(arID uint, tx *gorm.DB) error {
	return tx.Where("id = ?", arID).Delete(&ActionResource{}).Error
}

func DeleteActionResourcesByActionID(actionID uint, tx *gorm.DB) error {
	return tx.Where("action_id = ?", actionID).Delete(&ActionResource{}).Error
}

func DeleteActionResourcesByMenuID(id int, tx *gorm.DB) error {
	actions, err := GetMenuActionsWithMenuID(id)
	if err != nil {
		return err
	}

	ids := make([]uint, len(actions))
	for idx, action := range actions {
		ids[idx] = action.ID
	}

	if err := tx.Where("action_id in (?)", ids).Delete(&ActionResource{}).Error; err != nil {
		return err
	}
	return nil
}

func GetAllActionResources() (ActionResources, error) {
	resources := make(ActionResources, 0)
	if err := db.Model(&ActionResource{}).Find(&resources).Error; err != nil {
		return nil, err
	}
	return resources, nil
}

func GetActionResourcesWithActionID(actionID uint) (ActionResources, error) {
	resources := make(ActionResources, 0)
	if err := db.Model(&ActionResource{}).Where("action_id = ?", actionID).Find(&resources).Error; err != nil {
		return nil, err
	}
	return resources, nil
}

func (resources ActionResources) ToMapActionIDAsKey() map[uint]ActionResources {
	m := make(map[uint]ActionResources)
	for _, resource := range resources {
		m[resource.ActionID] = append(m[resource.ActionID], resource)
	}
	return m
}

func (resources ActionResources) ToMap() map[string]*ActionResource {
	m := make(map[string]*ActionResource)
	for _, resource := range resources {
		m[resource.Method+resource.Path] = resource
	}
	return m
}
